package com.example.administrator.x3picturetransliteration.Base;

import android.content.Context;
import android.content.Intent;

import com.example.administrator.x3picturetransliteration.Constants;
import com.example.administrator.x3picturetransliteration.Home.Activity.SignInActivity;
import com.example.administrator.x3picturetransliteration.Util.LoadingDialogUtil;
import com.example.administrator.x3picturetransliteration.Util.ToastUtil;
import com.orhanobut.logger.Logger;

import java.util.concurrent.TimeUnit;

import rx.Observable;
import rx.Observer;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

/**
 * 对Rx进行封装的基类
 * 2018/10/9.
 */

public class BaseRx<O> {

    private Context context;
    private Observable<O> mObservable;

    public BaseRx(Context context, Observable<O> mObservable){

        this.context = context;
        this.mObservable=mObservable;

    }

    public interface TheCallback<O>{

        Observable<O> setObservable();
    }

    public BaseRx<O> mObservable(final TheCallback<O> theCallback){

        if (context!=null)LoadingDialogUtil.getInstance(context).show();

        this.mObservable=mObservable
                .just(null)
                .flatMap(new Func1<Object, Observable<O>>() {

                    public Observable<O> call(Object o) {

                        return theCallback.setObservable();

                    }
                })
                .retryWhen(new RetryWithDelay(3, 3000))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());

        return this;
    }

    public Subscription mSubscribe(final Observer<O> mObserver){

        return mObservable.subscribe(new Observer<O>() {
            @Override
            public void onCompleted() {

                if (context!=null){

                    LoadingDialogUtil.getInstance(context).dismiss();
                }

                mObserver.onCompleted();

            }

            @Override
            public void onError(Throwable e) {



                if (context!=null){

                    LoadingDialogUtil.getInstance(context).dismiss();

                    if (e.toString().indexOf("请重新登录")!=-1){

                        new ToastUtil(context).getToast(false,"请重新登录").show();

                        Intent intent = new Intent(context, SignInActivity.class);
                        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                        intent.putExtra("notoken", "notoken");
                        context.startActivity(intent);

                    }else {

                        String ErrorString = Constants.getConstants().isToastJudge()?e.getMessage():Constants.getConstants().getAbnormal();
                        new ToastUtil(context).getToast(false,ErrorString).show();
                    }

                }

                Logger.e("Rx异常:" + e.toString());

                mObserver.onError(e);

            }

            @Override
            public void onNext(O o) {

                if (context!=null)LoadingDialogUtil.getInstance(context).dismiss();

                mObserver.onNext(o);

            }
        });


    }


    private class RetryWithDelay implements
            Func1<Observable<? extends Throwable>, Observable<?>> {

        private final int maxRetries;
        private final int retryDelayMillis;
        private int retryCount;

        public RetryWithDelay(int maxRetries, int retryDelayMillis) {
            this.maxRetries = maxRetries;
            this.retryDelayMillis = retryDelayMillis;
        }

        @Override
        public Observable<?> call(Observable<? extends Throwable> attempts) {
            return attempts
                    .flatMap(new Func1<Throwable, Observable<?>>() {
                        @Override
                        public Observable<?> call(Throwable throwable) {

                            if (++retryCount <= maxRetries) {

                                int pd1 = throwable.toString().indexOf("token异常"); //判断异常信息是否为token过期

                                if(pd1!=-1){

                                    //new LoginPresenter().getRefreshToken(); //重新请求token
                                    return Observable.timer(retryDelayMillis, TimeUnit.MILLISECONDS); //可以在这个if语句块儿里重新获取token然后在请求接口，这里重新获取token的工具类最好写一个回调方法用于获取token成功在请求接口
                                }

                            }

                            return Observable.error(throwable);
                        }
                    });
        }
    }

}
